﻿using System.Collections.Generic;
using EventStore.Common.Utils;

namespace EventStore.Projections.Core.Services.Processing {
	public abstract class EventFilter {
		private readonly bool _allEvents;
		private readonly bool _includeDeletedStreamEvents;
		private readonly HashSet<string> _events;

		/// <summary>
		/// 
		/// </summary>
		/// <param name="allEvents"></param>
		/// <param name="includeDeletedStreamEvents">indicates whether non-link stream tombstone or 
		/// metastream stream deleted events should be included. Links resolved into metastream 
		/// stream deleted events are not restricted</param>
		/// <param name="events"></param>
		protected EventFilter(bool allEvents, bool includeDeletedStreamEvents, HashSet<string> events) {
			_allEvents = allEvents;
			_includeDeletedStreamEvents = includeDeletedStreamEvents;
			_events = events;
		}

		public bool Passes(
			bool resolvedFromLinkTo, string eventStreamId, string eventName, bool isStreamDeletedEvent = false) {
			return (PassesSource(resolvedFromLinkTo, eventStreamId, eventName))
			       && ((_allEvents || _events != null && _events.Contains(eventName))
			           && (!isStreamDeletedEvent || _includeDeletedStreamEvents));
		}

		public bool PassesValidation(bool isJson, string data) {
			if (!isJson) return true;
			if (data is null) {
				return false;
			}
			return data.IsValidJson();
		}

		protected abstract bool DeletedNotificationPasses(string positionStreamId);
		public abstract bool PassesSource(bool resolvedFromLinkTo, string positionStreamId, string eventType);
		public abstract string GetCategory(string positionStreamId);

		public bool PassesDeleteNotification(string positionStreamId) {
			return !_includeDeletedStreamEvents && DeletedNotificationPasses(positionStreamId);
		}
	}
}
